import { ArrayMethods } from './arr'
export function observer(data) {
  // console.log('observer', data);
  // 对象数据处理
  if(typeof data !== 'object'  || data === null) {
    return data
  }
  return new Observer(data)
}

// object.defineProperty 只能对对象中的一个属性进行劫持

class Observer {
  constructor(value) {
    // 给 data 定义一个属性
    Object.defineProperty(value, '__ob__',  {
      enumerable: false, // 不可枚举
      value: this
    })
    // 判断数据是数组还是对象
    if(Array.isArray(value)) {
      // 数组
      value._proto__ = ArrayMethods
      // 数组对象
      this.observeArray(value)
    } else {
      // 对象
      this.walk(value) // 遍历
    }
  }
  walk(data) {
    let keys = Object.keys(data)
    for (let i = 0; i < keys.length; i++) {
      // 对每个属性进行劫持
      let key =  keys[i]
      let value = data[key]
      defineReactive(data, key, value)
    }
  }
  observeArray(value) {
    for(let i = 0; i < value.length; i++) {
      observer(value[i])
    }
  }
}

// 对对象中的属性进行劫持
function defineReactive(data, key, value) {
  // 递归进行深度代理
  observer(value)
  Object.defineProperty(data, key, {
    get() {
      // console.log('get获取');
      return value
    },
    set(newValue) {
      // console.log('set');
      if(newValue === value) return
      observer(newValue) // 用户初始化的值是对象
      value = newValue
    }
  })
}